package com.project.core.filter;

import com.project.core.jwt.AuditAware;
import com.project.core.jwt.JwtUtil;
import com.common.exception.ErrCode;
import com.common.exception.SeException;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;
import org.smartboot.http.common.utils.StringUtils;

@Slf4j
@SuppressWarnings({"CallToPrintStackTrace"})
@Component //index 为顺序位（不加，则默认为0）
public class AppFilter implements Filter {

    @Override
    public void doFilter(Context ctx, FilterChain chain) {
        //1.开始计时（用于计算响应时长）
        long start = System.currentTimeMillis();
        String info = " >>>>>> ";
        try {
            info += ctx.method() + " >>>>>> " + ctx.path() + " ======>请求耗时: ";

            if (ctx.path().contains("/favicon.ico")) {
                return;
            }

            // login 放行
            // if ("/user/login".equals(ctx.path())) {
            // 如果有 server.contextPath 配置时，ctx.path 为原始请求的 path ；ctx.pathNew 为去除 context-path 后的 path
            // 如果不会有 context-path，那无所谓
            // -- 说白了 就是 “去前缀”的效果
            // 另外，执行：ctx.forward("...") 后；ctx.path() 代表原始 path ；ctx.pathNew 则为  forward 的 path
            if ("/user/login".equals(ctx.pathNew())) {
                ErrCode.Not_Supported.isTrue(ctx.method().equals("POST"));
            } else {
                // 获取token
                String token = getToken(ctx);
                ErrCode.Operation_Denial.nonEmpty(token);

                // token 获取 userId
                Integer userId = JwtUtil.getUserIdFromToken(token);
                AuditAware.init(userId);
            }
            // 执行处理
            chain.doFilter(ctx);

            // 未处理设为404状态
            ErrCode.Not_Found.isTrue(ctx.getHandled());
        } catch (SeException e) {
            ctx.status(e.getCode());
            ctx.outputAsJson(ErrCode.get(e.getEc()));
            e.printStackTrace();
        } catch (Throwable e) {
            // 异常捕捉与控制（并标为500错误）
            ctx.status(ErrCode.System_Error.getCode());
            ctx.outputAsJson(ErrCode.get(ErrCode.System_Error, e.getMessage()));
            e.printStackTrace();
        }

        // 获得接口响应时长
        long times = System.currentTimeMillis() - start;

        info += times + " 毫秒，返回状态为：" + ctx.status();

        if (200 == ctx.status()) log.info(info);
        else log.error(info);
    }

    private String getToken(Context ctx) {
        String token1 = ctx.header("Authorization");
        String token2 = ctx.param("_t");
        if (StringUtils.isEmpty(token1)) {
            if (StringUtils.isEmpty(token2)) {
                return null;
            } else {
                return token2;
            }
        } else {
            return token1;
        }
    }
}
